/* QtLua -- Lua bindings for Qt
   Copyright (C) 2011, Jarek Pelczar

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 3 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General
   Public License along with this library; if not, write to the
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301 USA

*/

#include "wrap_QRect.h"
#include "qluascriptvalue.h"
#include "qluascriptcontext.h"
#include "qluaexception.h"
#include <QDebug>

QRect_Prototype::QRect_Prototype(QObject * parent)
    : QObject(parent)
{
}

QRect * QRect_Prototype::ptr() const
{
    QRect * ptr = qtlua_scriptvalue_cast<QRect>(thisObject());
    if(!ptr) {
        engine()->throwException(engine()->newException(QLatin1String("QRect_prototype: Unable to cast this object to QRect")));
    }
    return ptr;
}

QRectF * QRectF_Prototype::ptr() const
{
    QRectF * ptr = qtlua_scriptvalue_cast<QRectF>(thisObject());
    if(!ptr) {
        engine()->throwException(engine()->newException(QLatin1String("QRectF_prototype: Unable to cast this object to QRectF")));
    }
    return ptr;
}

QRectF_Prototype::QRectF_Prototype(QObject * parent)
    : QObject(parent)
{
}

QRect_wrapper::QRect_wrapper(QLuaScriptEngine * engine)
    : QObject(engine),
      QLuaScriptClass(engine)
{
    m_proto = engine->newQObject(new QRect_Prototype(engine),
                                 QLuaScriptEngine::ScriptOwnership);

    engine->setGlobal("QRect", engine->newQObject(this));
    engine->setGlobal("QRect_prototype", m_proto);

    qluaRegisterScriptMetaType<QRect>(engine,
                                       QRect_toScriptValue,
                                       QRect_fromScriptValue);
}

QRect_wrapper::QueryFlags QRect_wrapper::queryProperty(const QLuaScriptValue& object,
                                 const QByteArray& name)
{
    if(name == "newRect") {
        return HandlesCallAccess;
    }

    return 0;
}

QLuaScriptValue QRect_wrapper::property(const QLuaScriptValue& object,
                                      const QByteArray& name)
{
    if(name == "newRect") {
        return scriptEngine()->newFunction(new_rect);
    }

    return QLuaScriptValue();
}

QLuaScriptValue QRect_wrapper::prototype() const
{
    return m_proto;
}

QString QRect_wrapper::name() const
{
    return QLatin1String("QRect");
}

QLuaScriptValue QRect_wrapper::QRect_toScriptValue(QLuaScriptEngine * engine, const QRect * t)
{
    QLuaScriptValue value = engine->newUserDataWithGc<QRect>(engine->getGlobal("QRect_prototype"));
    QRect * obj = qtlua_scriptvalue_cast<QRect>(value);
    if(t)
        *obj = *t;
    return value;
}

void QRect_wrapper::QRect_fromScriptValue(const QLuaScriptValue& value, QRect * t)
{
    QRect * scriptT = qtlua_scriptvalue_cast<QRect>(value);
    if(scriptT) {
        *t = *scriptT;
    } else {
        qWarning("[QtLua] Trying to convert from another metatype of userdata to QRect");
    }
}

QLuaScriptValue QRect_wrapper::new_rect(QLuaScriptContext * context, QLuaScriptEngine * engine)
{
    QLuaScriptValue value = engine->newUserDataWithGc<QRect>(engine->getGlobal("QRect_prototype"));
    QRect * obj = qtlua_scriptvalue_cast<QRect>(value);
    if(context->argumentCount() == 1)
    {
        if(QRect * p2 = qtlua_scriptvalue_cast<QRect>(context->argument(0))) {
            *obj = *p2;
        } else if(context->argument(0).isTable()) {
            obj->setX(context->argument(0).property("x").toInteger());
            obj->setY(context->argument(0).property("y").toInteger());
            obj->setWidth(context->argument(0).property("width").toInteger());
            obj->setHeight(context->argument(0).property("height").toInteger());
        }
    } else if(context->argumentCount() == 4) {
        obj->setX(context->argument(0).toInteger());
        obj->setY(context->argument(1).toInteger());
        obj->setWidth(context->argument(3).toInteger());
        obj->setHeight(context->argument(4).toInteger());
    } else if(context->argumentCount() == 2) {
        if(QPoint * p1 = qtlua_scriptvalue_cast<QPoint>(context->argument(0))) {
            if(QPoint * p2 = qtlua_scriptvalue_cast<QPoint>(context->argument(1))) {
                *obj = QRect(*p1, *p2);
            } else if(QSize * s2 = qtlua_scriptvalue_cast<QSize>(context->argument(1))) {
                *obj = QRect(*p1, *s2);
            }
        }
    }
    return value;
}

QRectF_wrapper::QRectF_wrapper(QLuaScriptEngine * engine)
    : QObject(engine),
      QLuaScriptClass(engine)
{
    m_proto = engine->newQObject(new QRectF_Prototype(engine),
                                 QLuaScriptEngine::ScriptOwnership);

    engine->setGlobal("QRectF", engine->newQObject(this));
    engine->setGlobal("QRectF_prototype", m_proto);

    qluaRegisterScriptMetaType<QRectF>(engine,
                                       QRectF_toScriptValue,
                                       QRectF_fromScriptValue);
}

QRectF_wrapper::QueryFlags QRectF_wrapper::queryProperty(const QLuaScriptValue& object,
                                 const QByteArray& name)
{
    if(name == "newRect") {
        return HandlesCallAccess;
    }

    return 0;
}

QLuaScriptValue QRectF_wrapper::property(const QLuaScriptValue& object,
                                      const QByteArray& name)
{
    if(name == "newRect") {
        return scriptEngine()->newFunction(new_rectF);
    }

    return QLuaScriptValue();
}

QLuaScriptValue QRectF_wrapper::prototype() const
{
    return m_proto;
}

QString QRectF_wrapper::name() const
{
    return QLatin1String("QRectF");
}

QLuaScriptValue QRectF_wrapper::QRectF_toScriptValue(QLuaScriptEngine * engine, const QRectF * t)
{
    QLuaScriptValue value = engine->newUserDataWithGc<QRectF>(engine->getGlobal("QRectF_prototype"));
    QRectF * obj = qtlua_scriptvalue_cast<QRectF>(value);
    if(t)
        *obj = *t;
    return value;
}

void QRectF_wrapper::QRectF_fromScriptValue(const QLuaScriptValue& value, QRectF * t)
{
    QRectF * scriptT = qtlua_scriptvalue_cast<QRectF>(value);
    if(scriptT) {
        *t = *scriptT;
    } else {
        qWarning("[QtLua] Trying to convert from another metatype of userdata to QRectF");
    }
}

QLuaScriptValue QRectF_wrapper::new_rectF(QLuaScriptContext * context, QLuaScriptEngine * engine)
{
    QLuaScriptValue value = engine->newUserDataWithGc<QRectF>(engine->getGlobal("QRectF_prototype"));
    QRectF * obj = qtlua_scriptvalue_cast<QRectF>(value);
    if(context->argumentCount() == 1)
    {
        if(QRectF * p2 = qtlua_scriptvalue_cast<QRectF>(context->argument(0))) {
            *obj = *p2;
        } if(QRect * p2 = qtlua_scriptvalue_cast<QRect>(context->argument(0))) {
            *obj = *p2;
        } else if(context->argument(0).isTable()) {
            obj->setX(context->argument(0).property("x").toNumber());
            obj->setY(context->argument(0).property("y").toNumber());
            obj->setWidth(context->argument(0).property("width").toNumber());
            obj->setHeight(context->argument(0).property("height").toNumber());
        }
    } else if(context->argumentCount() == 4) {
        obj->setX(context->argument(0).toNumber());
        obj->setY(context->argument(1).toNumber());
        obj->setWidth(context->argument(3).toNumber());
        obj->setHeight(context->argument(4).toNumber());
    } else if(context->argumentCount() == 2) {
        if(QPointF * p1 = qtlua_scriptvalue_cast<QPointF>(context->argument(0))) {
            if(QPointF * p2 = qtlua_scriptvalue_cast<QPointF>(context->argument(1))) {
                *obj = QRectF(*p1, *p2);
            } else if(QSizeF * s2 = qtlua_scriptvalue_cast<QSizeF>(context->argument(1))) {
                *obj = QRectF(*p1, *s2);
            }
        }
    }
    return value;
}
